﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Reflection;
using System.Xml.Serialization;
using IKE.EntryLib;
using System.Collections;
using System.IO;
using IKE.LCAFormat.ILCD.Common;

namespace IKE.LCAFormat.ILCD.Process
{
    public class ProcessDataSet
    {
        public static IEnumerable<ProcessDataSet> AllProcesses(string path)
        {
            string[] files = Directory.GetFiles(path, "*.xml");
            foreach (var file in files)
            {
                yield return ProcessDataSet.Load(file,false);
            }
        }

        public static ProcessDataSet Load(string xmlFile,bool withoutExchanges=true)
        {
            if (File.Exists(xmlFile))
            {
                XDocument doc = XDocument.Load(xmlFile);
                return ProcessDataSet.Create(doc,withoutExchanges);
            }
            else
                return new ProcessDataSet();
        }

        public static ProcessDataSet Parse(string xmlStr, bool withoutExchanges = true)
        {
            XDocument doc = XDocument.Parse(xmlStr);
            return ProcessDataSet.Create(doc, withoutExchanges);
        }

        public void Save(string xmlFile, bool withoutExchanges = true)
        {
            this.Populate(withoutExchanges).Save(xmlFile);
        }

        public void Save(System.IO.TextWriter tw, bool withoutExchanges = true)
        {
            this.Populate(withoutExchanges).Save(tw);
        }

        public void Save(System.Xml.XmlWriter xmlWriter, bool withoutExchanges = true)
        {
            this.Populate(withoutExchanges).Save(xmlWriter);
        }
        public static ProcessDataSet Create(XDocument doc, bool withoutExchanges)
        {
            XNamespace process = "http://lca.jrc.it/ILCD/Process";
            XNamespace common = "http://lca.jrc.it/ILCD/Common";
            AutoSerializeBase.DictNamespaces["process"] = process;
            AutoSerializeBase.DictNamespaces["common"] = common;

            ProcessDataSet ds = new ProcessDataSet();
            var root = doc.Element(process + "processDataSet");
            ds.processInformation.FromElement(root.Element(process + "processInformation"));
            ds.modellingAndValidation.FromElement(root.Element(process + "modellingAndValidation"));
            ds.administrativeInformation.FromElement(root.Element(process + "administrativeInformation"));
            if (!withoutExchanges)
                ds.exchanges.FromElement(root.Element(process + "exchanges"));
            return ds;
        }
        public XDocument Populate(bool withoutExchanges)
        {
            XDocument doc = new XDocument();
            //doc.Declaration = new XDeclaration("1.0", "utf-8", "no");
            doc.Add(new XProcessingInstruction("xml-stylesheet", "version=\"1.0\" type=\"text/xsl\" href=\"../../stylesheets/process2html.xsl\""));

            XNamespace process = "http://lca.jrc.it/ILCD/Process";
            XNamespace common = "http://lca.jrc.it/ILCD/Common";
            XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
            XElement root = new XElement(process + "processDataSet",
                new XAttribute("xmlns", "http://lca.jrc.it/ILCD/Process"),
                new XAttribute(XNamespace.Xmlns + "common", "http://lca.jrc.it/ILCD/Common"),
                new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
                new XAttribute(xsi + "schemaLocation", "http://lca.jrc.it/ILCD/Process ../../schemas/ILCD_ProcessDataSet.xsd"),
                new XAttribute("locations", "../ILCDLocations.xml"),
                new XAttribute("version","1.1")
            );
            AutoSerializeBase.DictNamespaces["process"] = process;
            AutoSerializeBase.DictNamespaces["common"] = common;
            root.Add(processInformation.ToElement(process + "processInformation"));
            root.Add(modellingAndValidation.ToElement(process + "modellingAndValidation"));
            root.Add(administrativeInformation.ToElement(process + "administrativeInformation"));
            if (!withoutExchanges)
                root.Add(exchanges.ToElement(process + "exchanges"));
            doc.Add(root);
            return doc;
        }
        
        [DisplayUI(1)]
        public ProcessInformationType processInformation = new ProcessInformationType();

        [DisplayUI(2)]
        public ModellingAndValidationType modellingAndValidation = new ModellingAndValidationType();

        
        [DisplayUI(3)]
        public AdministrativeInformationType administrativeInformation = new AdministrativeInformationType();

        [DisplayUI(4)]
        public ExchangesType exchanges = new ExchangesType();
    }
}